﻿using System;
using System.Collections;
using ValidationEngine.Commons;
using ValidationEngine.Commons.Interfaces;

namespace ValidationEngine.Tools
{
    /// <summary>
    /// Provides methods to work with model
    /// </summary>
    public static class ModelHelper
    {
        /// <summary>
        /// Returns model's property value
        /// </summary>
        /// <param name="ctx">Validation context</param>
        /// <returns>Property value</returns>
        public static object GetPropertyValue(IValidationContext ctx)
        {
            return ctx.Model.GetType().GetProperty(ctx.PropertyName).GetValue(ctx.Model, null);
        }

        /// <summary>
        /// Returns model's property value
        /// </summary>
        /// <typeparam name="T">Return value type</typeparam>
        /// <param name="ctx">Validation context</param>
        /// <returns>Property value</returns>
        public static T GetPropertyValue<T>(IValidationContext ctx)
        {
            T res = default(T);
            try
            {
                res = (T)ctx.Model.GetType().GetProperty(ctx.PropertyName).GetValue(ctx.Model, null);
            }
            catch (Exception)
            {
            }
            return res;
        }

        public static decimal? GetDecimal(IValidationContext ctx)
        {
            decimal? res = null;

            try
            {
                res = Convert.ToDecimal(GetPropertyValue(ctx));
            }
            catch (Exception)
            { }
            return res;
        }

        /// <summary>
        /// If property is collection returns this collection. Null other way.
        /// </summary>
        /// <param name="ctx">Validation context</param>
        /// <param name="list">Collection representation of the property</param>
        public static void TryGetCollectionForProperty(IValidationContext ctx, out IList list)
        {
            list = GetPropertyValue(ctx) as IList;
        }

        /// <summary>
        /// Sets model validation info
        /// </summary>
        /// <param name="ctx">Validation context</param>
        /// <param name="propInfo">Validation info for property</param>
        public static void SetModelPropertyInfo(IValidationContext ctx, IValidationInfo propInfo)
        {
            ctx.Model.SetPropertyValidationInfo(ctx.PropertyName, propInfo);
        }
    }
}
